package com.gopay.bis.service.bank.impl.ebank;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.ebank.IcbcB2cManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.IcbcConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.icbc.ebank.pay.IcbcB2cMessage;
import com.gopay.common.domain.bank.icbc.ebank.pay.res.PayB2CRes;
import com.gopay.common.domain.bank.icbc.ebank.pay.res.PayBankB2CRes;
import com.gopay.common.domain.bank.icbc.ebank.pay.res.PaySubOrderB2CRes;
import com.gopay.common.domain.bank.icbc.ebank.query.res.CmsQueryB2CRes;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * 工行网银B2C业务实现
 * 
 * IcbcB2cBankServiceImpl.java
 * 
 * @author WangHongFei
 */
public class IcbcB2cBankServiceImpl implements BankInteractRemoteService {
	@Resource(name = "icbcB2cManager")
	private IcbcB2cManager icbcB2cManager;

	/**
	 * 支付类请求
	 * 
	 * @param BaseMessage
	 * @return Result
	 */
	@Override
	public Result pay(BaseMessage base) {
		Result result = new Result(false);
		try {
			IcbcB2cMessage messageB2C = new IcbcB2cMessage();
			BeanUtils.copyProperties(base, messageB2C);
			messageB2C = (IcbcB2cMessage) icbcB2cManager.sign(messageB2C);
			result.setDefaultModel(messageB2C);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6029);
		}
		return result;
	}

	/**
	 * 银行返回类请求
	 * 
	 * @param BaseMessage
	 * @return Result  
	 */
	
	/**
     * 订单状态true成功，false不成功
     */
    private boolean payStatus=false;
	@Override
	public Result bankBack(BaseMessage base) {
		Result result = new Result(false);
		try {
			boolean flag = false;
			IcbcB2cMessage messageB2C = new IcbcB2cMessage();
			BeanUtils.copyProperties(base, messageB2C);
			Map<String, Object> map = (Map) icbcB2cManager.verify(messageB2C);
			PayB2CRes payB2cRes = (PayB2CRes) map.get("res");
			PaySubOrderB2CRes subOrder = payB2cRes.getOrderInfo().getSubOrders().getSubOrder();
			payB2cRes.setOrderId(subOrder.getOrderIdRes());
			payB2cRes.setBankOrderId(subOrder.getOrderIdRes());
			payB2cRes.setAmount(new BigDecimal(TransUtils.amountConvert2Yuan(subOrder.getAmountRes())));
			flag = (Boolean) map.get("flag");
			result.setDefaultModel(flag);
			result.setModel("res", payB2cRes);
			result.setSuccess(true);
			// 验签成功入账
			if ((Boolean) result.getDefaultModel()) {
				PayB2CRes res = null;
				PayBankB2CRes bankRes = payB2cRes.getBankRes();
				String tranStat = bankRes.getTranStat();
				Map<String, String> param = new HashMap<String, String>();
				if (tranStat.equals("1")) {
					// 通知后台地址入账
					param.put("orderId", payB2cRes.getOrderId());
					param.put("amt", payB2cRes.getAmount().toString());
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "00");
					param.put("retCode", "00");
					param.put("retMsg", "验签成功");
					param.put("signData", messageB2C.getSignMessage());
					param.put("isFront", base.isFront()+"");
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(true);
				} else {
					// 通知后台地址该订单失败				
					param.put("orderId", payB2cRes.getOrderId());
					param.put("amt", payB2cRes.getAmount().toString());
					param.put("cardType", "Unknown");
					param.put("notifyNum", "1");
					param.put("payStatus", "01");
					param.put("retCode", "01");
					param.put("retMsg", "验签失败");
					param.put("signData", messageB2C.getSignMessage());
					param.put("isFront", base.isFront()+"");
					result.setModel("isNotifyCashier", param);
					result.setOrderStatus(false);
				}
			}

		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;
	}

	/**
	 * 银行查询类请求
	 * 
	 * @param BaseMessage
	 * @return Result
	 */
	@Override
	public Result query(BaseMessage base) {
		Result result = new Result(false);
		try {
			IcbcB2cMessage messageB2C = new IcbcB2cMessage();
			BeanUtils.copyProperties(base, messageB2C);
			CmsQueryB2CRes res = (CmsQueryB2CRes) icbcB2cManager.query(messageB2C);
			result.setDefaultModel(res);
			result.setSuccess(true);
			if(BisPayCheckUtils.checkExternalOrderID(messageB2C.getOrderId())){
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", messageB2C.getOrderId());
				param.put("amount", messageB2C.getAmount().toString());
				// 订单查询返回对象为空
				if (res == null) {
					// 查询订单为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				String returnCode = res.getEb().getPub().getRetCode(); // 订单查询交易返回码
				String retMsg = res.getEb().getPub().getRetMsg(); // 订单查询交易信息
				if (returnCode != null && !returnCode.equals(IcbcConstants.B2C_RETCODE_SUCCESS)) {
					// 查询订单错误
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", retMsg);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				String orderStatus = res.getEb().getOut().getRd().getResult(); // 订单状态
				if (orderStatus != null && !orderStatus.equals("")) {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					//成功处理
					if (orderStatus.equals(IcbcConstants.B2C_TRAN_ICBC_NC_DEAL_SUCC_1)){
						param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
						param.put("returnMessage", "交易成功");
					}else if (orderStatus.equals(IcbcConstants.B2C_TRAN_ICBC_NC_DEAL_SUCC_2)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_SUCCESS);
						param.put("returnMessage", "交易成功");
					}
					//失败处理
					else if (orderStatus.equals(IcbcConstants.B2C_TRAN_ICBC_NC_DEAL_FAIL)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_FAIL);
						param.put("returnMessage", "银行返回交易失败");
					}
					//不处理
					else if (orderStatus.equals(IcbcConstants.B2C_TRAN_ICBC_NC_DEAL_DEALING_1)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "银行返回支付交易可疑");
					} else if (orderStatus.equals(IcbcConstants.B2C_TRAN_ICBC_NC_DEAL_DEALING_2)) {
						param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "银行返回等待答复");
					}
				}
				// 没有查到订单
				else {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", retMsg);
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6033);
		}
		return result;
	}

	/**
	 * 银行退款类请求
	 * 
	 * @param BaseMessage
	 * @return Result
	 */
	@Override
	public Result refund(BaseMessage base) {
		return null;
	}

	/**
	 * 银行日终类请求
	 * 
	 * @param BaseMessage
	 * @return Result
	 */
	@Override
	public Result dayend(BaseMessage base) {
		return null;
	}

	@Override
	public Result queryBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

    @Override
    public Result refundBack(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result refundQuery(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

	@Override
	public Result sendBankRefund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

}
